package com.zmn.oms.third.taobao.msghandler.impl;

import com.alibaba.fastjson.JSON;
import com.taobao.api.internal.tmc.Message;
import com.taobao.api.internal.tmc.MessageStatus;
import com.zmn.oms.business.interfaces.log.OrderLogBService;
import com.zmn.oms.business.interfaces.warn.OrderWarnBService;
import com.zmn.oms.common.constant.OrderConsts;
import com.zmn.oms.common.constant.OrderLogConsts;
import com.zmn.oms.common.constant.OrderStatusConsts;
import com.zmn.oms.model.entity.log.OrderLog;
import com.zmn.oms.model.entity.warn.OrderWarn;
import com.zmn.oms.model.vo.work.ZsOrderWorkVO;
import com.zmn.oms.third.taobao.TaobaoTmcConstants;
import com.zmn.oms.third.taobao.TaobaoTmcUtil;
import com.zmn.oms.third.taobao.dto.UnservedWarningDTO;
import com.zmn.oms.zmn.aop.OrderWorkLogUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.Objects;

/**
 * 类描述：未服务预警消息处理器
 *
 * @author LiangHailong
 * @date 2019/07/24 18:06
 */
@Component("orderWarnTmcMsgHandler")
public class OrderWarnTmcMsgHandler extends TmcMsgHandlerBase {
    private static final Logger logger = LoggerFactory.getLogger(OrderWarnTmcMsgHandler.class);

    @Autowired
    private OrderLogBService orderLogBService;
    @Autowired
    private OrderWarnBService orderWarnBService;

    /**
     * 处理订服务预警消息
     * @param message
     * @param status
     */
    @Override
    public void procMsg(Message message, MessageStatus status) {
        try {
            UnservedWarningDTO unservedWarningDTO = TaobaoTmcUtil.parseMessageContent(message.getContent(), UnservedWarningDTO.class);
            saveWarnInfo(unservedWarningDTO, message);
        } catch (Exception e) {
            logger.info("【{}-消息-预警】消息处理失败，触发消息重发！ErrorMsg:[{}]", TaobaoTmcConstants.NAME_TMALL,
                    e.getMessage());
            logger.error(e.getMessage(), e);
            status.fail(); // 消息处理失败回滚，服务端需要重发
        }
    }

    /**
     * 保存预警信息
     * @param unservedWarningDTO
     * @param message
     */
    private void saveWarnInfo(UnservedWarningDTO unservedWarningDTO, Message message) {
        ZsOrderWorkVO orderWorkVO = null;

        // 找到预警消息中预警的工单
        // 预警消息中，当biz_type=1时，biz_id是工单id（即工单消息中的id字段，该字段保存在了工单表的outerId字段中）
        // 目前，淘宝只定义了biz_type=1的情况
        if (Objects.equals(1, unservedWarningDTO.getBizType())) {
            String outerId = Long.toString(unservedWarningDTO.getBizId());
            orderWorkVO = super.queryOrderByOuterId(outerId);
        }
        else {
            // TODO -lhl 如果淘宝方面扩展了biz_type（即biz_type!=1），biz_id的值是什么呢？如何通过该值找到系统中对应的订单呢？
        }

        if (orderWorkVO == null) {
            logger.warn("【{}-消息-预警】系统中没找到对应的订单！ message:[{}]", TaobaoTmcConstants.NAME_TMALL, message.getContent());
            return;
        }

        // 保存预警信息
        OrderWarn orderWarn = buildOrderWarn(orderWorkVO, unservedWarningDTO);
        orderWarnBService.addOrderWarn(orderWarn);

        // 存入工单日志
        OrderLog orderLog = buildOrderLog4WarnInfo(orderWorkVO, unservedWarningDTO);
        orderLogBService.save(orderLog);
    }

    /**
     * 将预警信息封装成工单日志对象
     * @param orderWork
     * @param unservedWarningDTO
     * @return
     */
    private OrderWarn buildOrderWarn(ZsOrderWorkVO orderWork, UnservedWarningDTO unservedWarningDTO) {
        OrderWarn orderWarn = new OrderWarn();
        orderWarn.setChannelId(orderWork.getChannelId());
        orderWarn.setBizStatus(OrderConsts.ORDER_WARN_STATUS_ACCEPT);
        orderWarn.setCreater("系统");

        orderWarn.setOrderId(orderWork.getOrderId());
        orderWarn.setWorkId(orderWork.getWorkId());
        orderWarn.setOuterId(unservedWarningDTO.getBizId());
        orderWarn.setOuterWarnId(unservedWarningDTO.getId());
        orderWarn.setOuterData(JSON.toJSONString(unservedWarningDTO));

        return orderWarn;
    }

    /**
     * 将预警信息封装成工单日志对象
     * @param orderWork
     * @param unservedWarningDTO
     * @return
     */
    private OrderLog buildOrderLog4WarnInfo(ZsOrderWorkVO orderWork, UnservedWarningDTO unservedWarningDTO) {
        OrderLog orderLog = new OrderLog();

        orderLog.setOrderId(orderWork.getOrderId());
        orderLog.setWorkId(orderWork.getWorkId());
        orderLog.setContent(unservedWarningDTO.getContent());

        orderLog.setType(OrderLogConsts.ORDER_LOG_TYPE_CHANNEL_REMARK);
        orderLog.setTypeName(OrderLogConsts.getOrderLogTypeName(OrderLogConsts.ORDER_LOG_TYPE_CHANNEL_REMARK));
        orderLog.setBeforeStatus(orderWork.getStatus());
        orderLog.setBeforeStatusName(OrderStatusConsts.getWorkStatusName(orderWork.getStatus()));
        orderLog.setBeforeResultStatus(orderWork.getResultStatus());
        orderLog.setBeforeResultStatusName(OrderStatusConsts.getWorkResultStatusName(orderWork.getResultStatus()));
        orderLog.setAfterStatus(orderWork.getStatus());
        orderLog.setAfterStatusName(OrderStatusConsts.getWorkStatusName(orderWork.getStatus()));
        orderLog.setAfterResultStatus(orderWork.getResultStatus());
        orderLog.setAfterResultStatusName(OrderStatusConsts.getWorkResultStatusName(orderWork.getResultStatus()));

        OrderWorkLogUtils.processOrderLogOperater(orderLog, null);

        return orderLog;
    }
}
